﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Media.Imaging;
using System.Net;
using System.Windows.Media;
using System.Threading;
using System.Windows.Threading;
using System.Xml;
using WeatherFrame;
using FlickrNet;

namespace WeatherImageCollection
{
    class WeatherImageCollector
    {
        string[] searchTerms = {
            "+beautiful,+landscape",
            "+weatherframe",
            "+rain,+landscape",
            "+snow,+landscape",
            "+raindrops",
            "+rain,+showers",
            "+rainy,+day",
            "+rainy,+night",
            "+rain,+day",
            "+rain,+night",
            "+snowy,+day",
            "+snowy,+night",
            "+lightning,+storm",
            "+sunny,+day",
            "+snowstorm",
            "+rainstorm",
            "+weather",
            "+foggy,+day",
            "+misty,+day",
            "+cloudscape",
            "+hailstone",
            "+hail",
            "+hailstorm",
            "+sleet",
            "+rain,+snow",
            "+moon",
            "+sun",
            "+sunset",
            "+snow,+night",
            "+blue,+sky",
            "+clear,+day",
            "+rain,+snowy",
            "+snow,+day",
            "+rain,+winter",
            "+winter",
            "+rain,+ice",
            "+snow",
            "+rain",
            "+amazing,+landscape",
            "+sky",
            "+landscape"
        };


        public string TargetFolder { get; set; }

        FlickrPhotoSearch fps = new FlickrPhotoSearch();

        public void CollectImages()
        {
            using (var fs = new FileStream(filename, FileMode.Open))
            {
                imageIndex.Read(fs);
            }

            foreach (string s in searchTerms)
            {
                var dir = Path.Combine(TargetFolder, s);
                if (Directory.Exists(dir)) continue;
                Directory.CreateDirectory(dir);
                var photos = fps.Search(s);
                foreach (var photo in photos)
                {
                    if (imageIndex.GetImageSetForId(photo.PhotoId) != null)
                    {
                        Console.Write("x");
                        continue;
                    }
                    Console.Write(".");
                    string uri = photo.MediumUrl;
                    string impath = Path.Combine(dir, photo.PhotoId + " " + s + ".jpg");
                    WriteImage(impath, uri);
                }
            }

        }

        private void WriteImage(string impath, string uri)
        {
            var img = new BitmapImage();
            img.BeginInit();
            img.UriSource = new Uri(uri);
            img.CreateOptions = BitmapCreateOptions.None;
            img.CacheOption = BitmapCacheOption.OnLoad;
            img.EndInit();
            while (img.IsDownloading) DoEvents();
            using (FileStream fs = new FileStream(impath, FileMode.Create))
            {
                JpegBitmapEncoder jbe = new JpegBitmapEncoder();
                jbe.Frames.Add(BitmapFrame.Create(img));
                jbe.Save(fs);
            }
        }

        public void DoEvents()
        {
            DispatcherFrame frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(delegate(object param)
            {
                frame.Continue = false;
                return null;
            }), null);
            Dispatcher.PushFrame(frame);
        }


        string filename = Path.Combine(@"C:\Users\John\Documents\Visual Studio 2010\Projects\WeatherFrame\WeatherFrame", "ImageIndex.xml");
        ImageIndex imageIndex = new ImageIndex();

        internal void MakeImageIndex()
        {
            string sortedFolder = Path.Combine(TargetFolder, "Sorted");
            var dirs = Directory.EnumerateDirectories(sortedFolder);
            //            using (XmlWriter x = XmlWriter.Create(,xws))
            int tot = 0;
            foreach (var d in dirs)
            {
                var cis = FindConditionImages(d);
                imageIndex.Add(cis);
                int ct = cis.Images.Count;
                if (ct == 0) Console.Write("***No images found***");
                tot += ct;
            }
            Console.WriteLine("TOTAL=" + tot);            
            using (var fs = new FileStream(filename, FileMode.Create))
            {
                imageIndex.Write(fs);
            }
        }

        private ConditionImageSet FindConditionImages(string d)
        {
            string condname = Path.GetFileName(d);
            var cis = new ConditionImageSet { Name = condname };
            Console.Write(cis.Name + ": ");
            var imgs = Directory.EnumerateFiles(d,"*.jpg");
            int ct = 0;
            foreach (var impath in imgs)
            {
                var name = Path.GetFileNameWithoutExtension(impath);
                var k = name.IndexOf(" ");
                if (k == -1) continue;
                ct++;
                string id = name.Substring(0, k);
                var cis2 = imageIndex.GetImageSetForId(id);
                if (cis2!=null)
                {
                    Console.WriteLine(Environment.NewLine + "*** Duplicate image: " + id+" in "+cis2.Name);
                    continue;
                }
                try
                {
                    var im = new ConditionImage { FlickrId = id };
                    fps.GetPhotoInfo(im);
                    cis.Images.Add(im);
                    Console.Write(".");
                }
                catch (Exception ex)
                {
                    Console.Write("!");
                }
            }
            Console.WriteLine(" "+ ct + " images");
            return cis;
        }




        internal void CheckImageIndex()
        {
            using (var fs = new FileStream(filename, FileMode.Open))
            {
                imageIndex.Read(fs);
            }
            string checkFolder = @"C:\temp\wfcheck";
            foreach (string s in imageIndex.condImageLookup.Keys)
            {
                Console.Write(s+":");
                var cis = imageIndex.condImageLookup[s];
                string dir = Path.Combine(checkFolder, s);
                Directory.CreateDirectory(dir);
                foreach (var im in cis.Images)
                {
                    
                    string filename = Path.Combine(dir, im.FlickrId + ".jpg");
                    if (!File.Exists(filename))
                    {
                        WriteImage(filename, im.SmallUri);
                        Console.Write(".");
                    }
                    else
                    {
                        Console.Write("o");
                    }
                }
                Console.WriteLine();
            }
        }
    }
}
